home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
Source
/
stuff
/
comp14.c
next >
Wrap
Text File
|
1994-05-04
|
7KB
|
273 lines
/*
* Copyright (c) 1985, 1986 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* James A. Woods, derived from original work by Spencer Thomas
* and Joseph Orost.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "stuff.h"
typedef long int code_int;
typedef long int count_int;
typedef long int cmp_code_int;
typedef unsigned char char_type;
enum {maxbits = 14};
char_type inbuf[1024+64];
char_type outbuf[1024+2048];
long bytes_in;
long bytes_out;
count_int *htab;
unsigned short *codetab;
void compress(int fdin, int fdout)
{
register long hp;
int rpos;
int outbits;
int rlop;
int rsize;
int stcode;
code_int free_ent;
int boff;
int n_bits;
int ratio;
long checkpoint;
code_int extcode;
union
{
long code;
struct
{
char_type c;
unsigned short ent;
} e;
} fcode;
if (!htab) htab = (void *)NewPtr(18013*sizeof(count_int));
if (!codetab) codetab = (void *)NewPtr(18013*sizeof(unsigned short));
ratio = 0;
checkpoint = 10000;
extcode = (1L << (n_bits = 9))+1;
stcode = 1;
free_ent = 257;
memset(outbuf, 0, sizeof(outbuf));
bytes_out = 0; bytes_in = 0;
UpdateProgress(0);
boff = outbits = 0;
fcode.code = 0;
memset(htab, -1, 18013*sizeof(count_int));
do
{
long inOutCount = 1024;
OSErr iErr = FSRead(fdin,&inOutCount,inbuf);
if (iErr != eofErr) ChkOsErr(iErr);
rsize = inOutCount;
if ((rsize ) > 0)
{
UpdateProgress(prog_div);
crc = updcrc(crc, inbuf, rsize);
if (bytes_in == 0)
{
fcode.e.ent = inbuf[0];
rpos = 1;
}
else
rpos = 0;
rlop = 0;
do
{
if (free_ent >= extcode && fcode.e.ent < 257)
{
if (n_bits < maxbits)
{
boff = outbits = (outbits-1)+((n_bits<<3)-((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
if (++n_bits < maxbits)
extcode = (1L << (n_bits))+1;
else
extcode = (1L << (n_bits));
}
else
{
extcode = (1L << (16))+1024;
stcode = 0;
}
}
if (!stcode && bytes_in >= checkpoint && fcode.e.ent < 257)
{
register long int rat;
checkpoint = bytes_in + 10000;
if (bytes_in > 0x007fffff)
{
rat = (bytes_out+(outbits>>3)) >> 8;
if (rat == 0)
rat = 0x7fffffff;
else
rat = bytes_in / rat;
}
else
rat = (bytes_in << 8) / (bytes_out+(outbits>>3));
if (rat >= ratio)
ratio = (int)rat;
else
{
ratio = 0;
memset(htab, -1, 18013*sizeof(count_int));
{
register char_type *p = &(outbuf)[(outbits)>>3];
register long i = ((long)(256))<<((outbits)&0x7);
p[0] |= (char_type)(i);
p[1] |= (char_type)(i>>8);
p[2] |= (char_type)(i>>16);
(outbits) += (n_bits);
}
boff = outbits = (outbits-1)+((n_bits<<3)-((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
extcode = (1L << (n_bits = 9))+1;
free_ent = 257;
stcode = 1;
}
}
if (outbits >= (1024<<3))
{
long inOutCount = 1024;
ChkOsErr(FSWrite(fdout,&inOutCount,outbuf));
outbits -= (1024<<3);
boff = -(((1024<<3)-boff)%(n_bits<<3));
bytes_out += 1024;
memcpy(outbuf, outbuf+1024, (outbits>>3)+1);
memset(outbuf+(outbits>>3)+1, '\0', 1024);
}
{
register int i;
i = rsize-rlop;
if ((code_int)i > extcode-free_ent) i = (int)(extcode-free_ent);
if (i > ((sizeof(outbuf) - 32)*8 - outbits)/n_bits)
i = ((sizeof(outbuf) - 32)*8 - outbits)/n_bits;
if (!stcode && (long)i > checkpoint-bytes_in)
i = (int)(checkpoint-bytes_in);
rlop += i;
bytes_in += i;
}
goto next;
hfound: fcode.e.ent = codetab[hp];
next: if (rpos >= rlop)
goto endlop;
next2: fcode.e.c = inbuf[rpos++];
{
register code_int i;
hp = (((long)(fcode.e.c)) << (14-8)) ^ (long)(fcode.e.ent);
if ((i = htab[hp]) == fcode.code)
goto hfound;
if (i != -1)
{
long disp;
disp = (18013 - hp)-1;
do
{
if ((hp -= disp) < 0) hp += 18013;
if ((i = htab[hp]) == fcode.code)
goto hfound;
}
while (i != -1);
}
}
{
register char_type *p = &(outbuf)[(outbits)>>3];
register long i = ((long)(fcode.e.ent))<<((outbits)&0x7);
p[0] |= (char_type)(i);
p[1] |= (char_type)(i>>8);
p[2] |= (char_type)(i>>16);
(outbits) += (n_bits);
};
{
register long fc;
fc = fcode.code;
fcode.e.ent = fcode.e.c;
if (stcode)
{
codetab[hp] = (unsigned short)free_ent++;
htab[hp] = fc;
}
}
goto next;
endlop: if (fcode.e.ent >= 257 && rpos < rsize)
goto next2;
if (rpos > rlop)
{
bytes_in += rpos-rlop;
rlop = rpos;
}
}
while (rlop < rsize);
}
}
while (rsize > 0);
if (bytes_in > 0)
{
register char_type *p = &(outbuf)[(outbits)>>3];
register long i = ((long)(fcode.e.ent))<<((outbits)&0x7);
p[0] |= (char_type)(i);
p[1] |= (char_type)(i>>8);
p[2] |= (char_type)(i>>16);
(outbits) += (n_bits);
}
{
OSErr iErr;
long inOutCount = (outbits+7)>>3;
ChkOsErr(FSWrite(fdout,&inOutCount,outbuf));
bytes_out += (outbits+7)>>3;
}
UpdateProgress(0);
}
void copy(int fdin, int fdout)
{
long inOutCount;
OSErr iErr;
UpdateProgress(0);
bytes_out = 0;
do
{
inOutCount = 32768;
iErr = FSRead(fdin,&inOutCount,codetab);
if (iErr != eofErr) ChkOsErr(iErr);
if (inOutCount > 0)
{
ChkOsErr(FSWrite(fdout,&inOutCount,codetab));
bytes_out += inOutCount;
UpdateProgress(prog_div<<5);
}
}
while (inOutCount > 0);
UpdateProgress(0);
}